#ifndef TRAVELINGSALESMANENVIRONMENT_H_
#define TRAVELINGSALESMANENVIRONMENT_H_

#define NEWLINE 13

#include <iostream>
#include <fstream>
#include <string>
#include <iomanip>
#include <sstream>
#include "../Environment.h"
#include "../../Solution/PermutationEncoded/PermutationEncodedSolution.h"
#include "../../Solution/Solution.h"
#include "../../Crossover/Crossover.h"
#include "../../Crossover/SinglePoint/SinglePointCrossover.h"
#include "../../Crossover/TwoPoint/TwoPointCrossover.h"
#include "../../Crossover/RandomGeneration/RandomGenerationCrossover.h"
#include "../../Random/MyRandom.h"
#include "../../Exception/GA_Exception.h"

/** Environment for solving the Traveling Salesman problem.
 */
template <typename T=PermutationEncodedSolution> class TravelingSalesmanEnvironment : public Environment
{
    public:
        TravelingSalesmanEnvironment();
        void generateRandomPopulation(vector<Solution*> &, unsigned int); /**< Fills the provided vector with a randomly generated population    */
        double evaluateFitness(Solution*);                       /**< Evaluates the fitness of the provided solution                    */
        void outputTable();                                      /**< Outputs the lookup table of trip lengths                          */
        void configure();                                        /**< Configures the environment                                        */
        void configure(string);                                  /**< Configures the environment from a file                            */
        void configure(int, int ,int);                           /**< Configures the environment from the function parameters           */
        Crossover* configureCrossover();                         /**< Returns a crossover appropriate to use with this environment      */
        virtual ~TravelingSalesmanEnvironment();
        
        static string getName();
        static Environment* getEnvironment();                    /**< Factory method for generating Traveling Salesman Environments     */
        
    private:
    	vector<vector<int> > lookupTable;
    	unsigned int tripHops;
    	int maxTripLength;
    	int minTripLength;
    	bool configured;
        
    	void generateRandomTable();
        void readFile(string);
};

template <typename T>
Environment* TravelingSalesmanEnvironment<T>::getEnvironment()
{ 
   return new TravelingSalesmanEnvironment<PermutationEncodedSolution>(); 
};

#endif /*TRAVELINGSALESMANENVIRONMENT_H_*/
